<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>AngelScript: Template types</title>

<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
  $(document).ready(initResizable);
</script>


</head>
<body>
<div id="top"><!-- do not remove this div! -->


<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  
  
  <td style="padding-left: 0.5em;">
   <div id="projectname">AngelScript
   
   </div>
   
  </td>
  
  
  
   
  
 </tr>
 </tbody>
</table>
</div>

<!-- Generated by Doxygen 1.7.5.1 -->
</div>
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
  initNavTree('doc_adv_template.html','');
</script>
<div id="doc-content">
<div class="header">
  <div class="headertitle">
<div class="title">Template types </div>  </div>
</div>
<div class="contents">
<div class="textblock"><p>A template type in AngelScript works similarly to how templates work in C++. The scripts will be able to instanciate different forms of the template type by specifying which subtype that should be used. The methods for the instance will then be adapted to this subtype, so that the correct handling of parameters and return types will be applied.</p>
<p>The implementation of the template type is not a C++ template though, instead it must be implemented as a generic class that can determine what to do dynamically at runtime based on the subtype for which it was instanciated. This is obviously a lot less efficient than having specific implementations for each type, and for that reason AngelScript permits the application to register a template specialization where the extra performance is needed.</p>
<p>This gives the best of both worlds, performance where the subtype is known before hand, and support for all other types that cannot be pre-determined.</p>
<h2><a class="anchor" id="doc_adv_template_1"></a>
Registering the template type</h2>
<p>The template registration is registered similarly to normal <a class="el" href="doc_reg_basicref.html">reference types</a>, with a few differences. The name of the type is formed by the name of the template type plus the name of the subtype with angle brackets. The type flag asOBJ_TEMPLATE must also be used.</p>
<div class="fragment"><pre class="fragment"><span class="comment">// Register the template type</span>
r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a29c6c087c8c5b5cdb6271cfd161cc5a6" title="Registers a new object type.">RegisterObjectType</a>(<span class="stringliteral">&quot;myTemplate&lt;class T&gt;&quot;</span>, 0, <a class="code" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861" title="A reference type.">asOBJ_REF</a> | <a class="code" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aacc1d835f9c25043cef86026a4aa6a470" title="A garbage collected type. Only valid for reference types.">asOBJ_GC</a> | <a class="code" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aae8de459b4106475aa8766edb5b088aac" title="A template type.">asOBJ_TEMPLATE</a>); assert( r &gt;= 0 );
</pre></div><p>The template type doesn't have to be <a class="el" href="doc_gc_object.html">garbage collected</a>, but since you may not know which subtypes it will be instanciated for, it is usually best to implement that support.</p>
<p>When registering the behaviours, methods, and properties for the template type the type is identified with the name and subtype within angle brackets, but without the class token, e.g. <code>myTemplate&lt;T&gt;</code>. The sub type is identified by just the name of the subtype as it was declared in the call to RegisterObjectType.</p>
<p>The factory behaviour for the template type is also different. In order for the implementation to know which subtype it is instanciated for the factory receives the <a class="el" href="classas_i_object_type.html">asIObjectType</a> of the template instance as a hidden first parameter. When registering the factory this hidden parameter is reflected in the declaration, for example as <code>int &amp;in</code>.</p>
<div class="fragment"><pre class="fragment"><span class="comment">// Register the factory behaviour</span>
r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a7ea3c93dea338b0287027de0e4895dcb" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;myTemplate&lt;T&gt;&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a0b3db16eea35213b6f41f8d19dc1bd4c" title="Factory.">asBEHAVE_FACTORY</a>, <span class="stringliteral">&quot;myTemplate&lt;T&gt;@ f(int&amp;in)&quot;</span>, <a class="code" href="angelscript_8h.html#a153aee5a6228913a469b6e6867e54efb" title="Returns an asSFuncPtr representing the function specified by the name, parameter list, and return type.">asFUNCTIONPR</a>(myTemplateFactory, (<a class="code" href="classas_i_object_type.html" title="The interface for an object type.">asIObjectType</a>*), myTemplate*), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4" title="A cdecl function.">asCALL_CDECL</a>); assert( r &gt;= 0 );
</pre></div><p>The list factory, used to instanciate objects with initialization lists, is registered in the same way, i.e.:</p>
<div class="fragment"><pre class="fragment"><span class="comment">// Register the list factory behaviour</span>
r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a7ea3c93dea338b0287027de0e4895dcb" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;myTemplate&lt;T&gt;&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5aea078bc3b877ce33a2335e78ddb4938d" title="Factory used exclusively for initialization lists.">asBEHAVE_LIST_FACTORY</a>, <span class="stringliteral">&quot;myTemplate&lt;T&gt;@ f(int&amp;in, uint)&quot;</span>, <a class="code" href="angelscript_8h.html#a153aee5a6228913a469b6e6867e54efb" title="Returns an asSFuncPtr representing the function specified by the name, parameter list, and return type.">asFUNCTIONPR</a>(myTemplateListFactory, (<a class="code" href="classas_i_object_type.html" title="The interface for an object type.">asIObjectType</a>*, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>), myTemplate*), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4" title="A cdecl function.">asCALL_CDECL</a>); assert( r &gt;= 0 );
</pre></div><p>Remember that since the subtype must be determined dynamically at runtime, it is not possible to declare functions to receive the subtype by value, nor to return it by value. Instead you'll have to design the methods and behaviours to take the type by reference. It is possible to use object handles, but then the script engine won't be able to instanciate the template type for primitives and other values types.</p>
<dl class="see"><dt><b>See also:</b></dt><dd><a class="el" href="doc_addon_array.html">array template object</a></dd></dl>
<h2><a class="anchor" id="doc_adv_template_4"></a>
Validating template instantiations at compile time</h2>
<p>In order to avoid unnecessary runtime validations of invalid template instantiations, the application should preferably register the <a class="el" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a8c9afe12ff833cd09bd893e1408b9103">asBEHAVE_TEMPLATE_CALLBACK</a> behaviour. This is a special behaviour function that the script engine will invoke everytime a new template instance type is generated. The callback function can then perform necessary validations to verify if the type can be handled, and if not tell the engine that the instance isn't supported.</p>
<p>The callback function must be a global function that receives an <a class="el" href="classas_i_object_type.html" title="The interface for an object type.">asIObjectType</a> pointer, and should return a boolean. If the template instance is valid the return value should be true.</p>
<div class="fragment"><pre class="fragment"><span class="comment">// Register the template callback</span>
r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a7ea3c93dea338b0287027de0e4895dcb" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;myTemplate&lt;T&gt;&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a8c9afe12ff833cd09bd893e1408b9103" title="Callback for validating template instances.">asBEHAVE_TEMPLATE_CALLBACK</a>, <span class="stringliteral">&quot;bool f(int &amp;in)&quot;</span>, <a class="code" href="angelscript_8h.html#a78f8f2c7f1c88b12e74a5ac47b4184ae" title="Returns an asSFuncPtr representing the function specified by the name.">asFUNCTION</a>(myTemplateCallback), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4" title="A cdecl function.">asCALL_CDECL</a>); assert( r &gt;= 0 );
</pre></div><p>Here's an example callback function:</p>
<div class="fragment"><pre class="fragment"><span class="keywordtype">bool</span> myTemplateCallback(<a class="code" href="classas_i_object_type.html" title="The interface for an object type.">asIObjectType</a> *ot)
{
  <span class="comment">// This template will only support primitive types</span>
  <span class="keywordtype">int</span> typeId = ot-&gt;<a class="code" href="classas_i_object_type.html#a0107578e233ec491808ae7e1b35a9a6f" title="Returns the type id of the template sub type.">GetSubTypeId</a>();
  <span class="keywordflow">if</span>( typeId &amp; <a class="code" href="angelscript_8h.html#ae8c3a67a97321be53181e9ed396ad83aa09eef59280d15a58c75e0c8983a3c3af" title="If any of these bits are set, then the type is an object.">asTYPEID_MASK_OBJECT</a> )
  {
    <span class="comment">// The script is attempting to instantiate the </span>
    <span class="comment">// template with an object type, this is not allowed.</span>
    <span class="keywordflow">return</span> <span class="keyword">false</span>;
  }
    
  <span class="comment">// Primitive types are allowed</span>
  <span class="keywordflow">return</span> <span class="keyword">true</span>;
}
</pre></div><h2><a class="anchor" id="doc_adv_template_2"></a>
Template specializations</h2>
<p>When registering a template specialization you override the template instance that AngelScript would normally do when compiling a declaration with the template type. This allow the application to register a completely different object with its own implementation for template specializations. Obviously it is recommended that the template specialization is registered so that to the script writer it is transparent, i.e. try to avoid having different method names or behaviours for the template type and template specializations.</p>
<p>With the exception of the type name, a template specialization is registered exactly like a <a class="el" href="doc_register_type.html">normal type</a>.</p>
<div class="fragment"><pre class="fragment"><span class="comment">// Register a template specialization for the float subtype</span>
r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a29c6c087c8c5b5cdb6271cfd161cc5a6" title="Registers a new object type.">RegisterObjectType</a>(<span class="stringliteral">&quot;myTemplate&lt;float&gt;&quot;</span>, 0, <a class="code" href="angelscript_8h.html#a855d86fa9ee15b9f75e553ee376b5c7aa9450e038342b36c745858d2e5ae4b861" title="A reference type.">asOBJ_REF</a>); assert( r &gt;= 0 );
  
<span class="comment">// Register the factory (there are no hidden parameters for specializations)</span>
r = engine-&gt;<a class="code" href="classas_i_script_engine.html#a7ea3c93dea338b0287027de0e4895dcb" title="Registers a behaviour for the object type.">RegisterObjectBehaviour</a>(<span class="stringliteral">&quot;myTemplate&lt;float&gt;&quot;</span>, <a class="code" href="angelscript_8h.html#a7e38df5b10ec8cbf2a688f1d114097c5a0b3db16eea35213b6f41f8d19dc1bd4c" title="Factory.">asBEHAVE_FACTORY</a>, <span class="stringliteral">&quot;myTemplate&lt;float&gt;@ f()&quot;</span>, <a class="code" href="angelscript_8h.html#a78f8f2c7f1c88b12e74a5ac47b4184ae" title="Returns an asSFuncPtr representing the function specified by the name.">asFUNCTION</a>(myTemplateFloatFactory, (), myTemplateFloat*), <a class="code" href="angelscript_8h.html#a3ec92ea3c4762e44c2df788ceccdd1e4a68ae43cc91cdfc3fa4590c9e6164e4f4" title="A cdecl function.">asCALL_CDECL</a>); assert( r &gt;= 0 );
</pre></div><h2><a class="anchor" id="doc_adv_template_3"></a>
Current limitations</h2>
<ul>
<li>Template types are currently limited to reference types only, i.e. it must be registered with a factory and addref and release behaviours.</li>
</ul>
<ul>
<li>Only one template subtype can be used at the moment. </li>
</ul>
</div></div>
</div>
  <div id="nav-path" class="navpath">
    <ul>

    <li class="footer">Generated on Sun Jan 29 2012 15:41:03 for AngelScript by
    <a href="http://www.doxygen.org/index.html">
    <img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.5.1 </li>
   </ul>
 </div>


</body>
</html>
